/****************************************************************
 * Fulguro
 * Copyright (C) 2004 Christophe Clienti
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 ***************************************************************/


#include <math.h>
#include <flgrCoreDispatch.h>
#include <flgrCoreData.h>
#include <flgrCoreIO.h>
#include <flgrCoreMalloc.h>
#include <flgrCoreArithDef.h>
#include "flgrArithComplex.h"


/*!
 * \defgroup group_fulguro_arith_cplx Complex Arithmetic
 * Complex Arithmetic
 * \ingroup group_fulguro_arith
 * @{
 */


/**********************************************************************************************/
/******************************************** 1D **********************************************/
/**********************************************************************************************/


/////////////////////////////////////////////////////////////////////////
// macro for different type of flgr1d_arith_complex_module
/////////////////////////////////////////////////////////////////////////
#define FLGR_MACRO_ARITH_COMPLEX_MODULE_1D(dtype,op)			\
  dtype *isrc = (dtype*) cdatsrc->array;				\
  dtype *rdest = (dtype*) rdatdest->array;				\
  dtype result;								\
  dtype val1,val2;							\
  int spp = cdatsrc->spp;						\
  int length = rdatdest->length;					\
  int i,j;								\
									\
  FLGR_DECLARE_FUNCTION;						\
									\
  for(j=0,i=0 ; i<length ; j+=spp,i++) {				\
    val1 = flgr_get_array_##dtype(isrc,j);				\
    val2 = flgr_get_array_##dtype(isrc,j+1);				\
    result = op(val1*val1+val2*val2);					\
    flgr_set_array_##dtype(rdest,i,result);				\
  }									\
									\
  return



void flgr1d_arith_complex_module_fgBIT(FLGR_Data1D *rdatdest, FLGR_Data1D *cdatsrc) {
  flgr_no_define_type_function(FLGR_BIT);
}
void flgr1d_arith_complex_module_fgUINT8(FLGR_Data1D *rdatdest, FLGR_Data1D *cdatsrc) {
  flgr_no_define_type_function(FLGR_UINT8);
}
void flgr1d_arith_complex_module_fgUINT16(FLGR_Data1D *rdatdest, FLGR_Data1D *cdatsrc) {
  flgr_no_define_type_function(FLGR_UINT16);
}
void flgr1d_arith_complex_module_fgUINT32(FLGR_Data1D *rdatdest, FLGR_Data1D *cdatsrc) {
  flgr_no_define_type_function(FLGR_UINT32);
}
void flgr1d_arith_complex_module_fgINT8(FLGR_Data1D *rdatdest, FLGR_Data1D *cdatsrc) {
  flgr_no_define_type_function(FLGR_INT8);
}
void flgr1d_arith_complex_module_fgINT16(FLGR_Data1D *rdatdest, FLGR_Data1D *cdatsrc) {
  flgr_no_define_type_function(FLGR_INT16);
}
void flgr1d_arith_complex_module_fgINT32(FLGR_Data1D *rdatdest, FLGR_Data1D *cdatsrc) {
  flgr_no_define_type_function(FLGR_INT32);
}
void flgr1d_arith_complex_module_fgFLOAT32(FLGR_Data1D *rdatdest, FLGR_Data1D *cdatsrc) {
  FLGR_MACRO_ARITH_COMPLEX_MODULE_1D(fgFLOAT32,sqrtl);
}
void flgr1d_arith_complex_module_fgFLOAT64(FLGR_Data1D *rdatdest, FLGR_Data1D *cdatsrc) {
  FLGR_MACRO_ARITH_COMPLEX_MODULE_1D(fgFLOAT64,sqrt);
}
////////////////////////////////////////////////////////////////////////////
/*! Compute module of a complex data
 *  @param rdatdest : pointer to FLGR_Data1D (real, spp=1)
 *  @param cdatsrc : pointer to FLGR_Data1D (complex, spp=2)
 *  @returns FLGR_RET_OK, ...
 */
//////////////////////////////////////////////////////////////////
FLGR_Ret flgr1d_arith_complex_module(FLGR_Data1D *rdatdest, FLGR_Data1D *cdatsrc) {
  FLGR_Ret ret;

  FLGR_DECLARE_FUNCTION;
			
  if((rdatdest==NULL) || (cdatsrc==NULL)) {
    POST_ERROR("Null objects!\n");
    return FLGR_RET_NULL_OBJECT;
  }

  if(rdatdest->spp != 1) {
    POST_ERROR("destination must be scalar\n");
    return FLGR_RET_VECTOR_SIZE_ERROR;
  }

  if(cdatsrc->spp != 2) {
    POST_ERROR("source must be complex (spp=2)\n");
    return FLGR_RET_VECTOR_SIZE_ERROR;
  }

  if((ret = flgr1d_is_data_same_type(rdatdest,cdatsrc)) != FLGR_RET_OK) return ret;
  if((ret = flgr1d_is_data_same_length(rdatdest,cdatsrc)) != FLGR_RET_OK) return ret;

  FLGR_DISPATCH_PROCEDURE(rdatdest->type,flgr1d_arith_complex_module,rdatdest,cdatsrc);

}






/////////////////////////////////////////////////////////////////////////
// macro for different type of flgr1d_arith_complex_module
/////////////////////////////////////////////////////////////////////////
#define FLGR_MACRO_ARITH_COMPLEX_ARGUMENT_1D(dtype,op1)			\
  dtype *isrc = (dtype*) cdatsrc->array;				\
  dtype *rdest = (dtype*) rdatdest->array;				\
  dtype result;								\
  dtype val1,val2;							\
  int spp = cdatsrc->spp;						\
  int length = rdatdest->length;					\
  int i,j;								\
									\
  FLGR_DECLARE_FUNCTION;						\
									\
  for(j=0,i=0 ; i<length ; j+=spp,i++) {				\
    val1 = flgr_get_array_##dtype(isrc,j);				\
    val2 = flgr_get_array_##dtype(isrc,j+1);				\
    result = op1(val2,val1);						\
    flgr_set_array_##dtype(rdest,i,result);				\
  }									\
									\
  return

void flgr1d_arith_complex_argument_fgBIT(FLGR_Data1D *rdatdest, FLGR_Data1D *cdatsrc) {
  flgr_no_define_type_function(FLGR_BIT);
}
void flgr1d_arith_complex_argument_fgUINT8(FLGR_Data1D *rdatdest, FLGR_Data1D *cdatsrc) {
  flgr_no_define_type_function(FLGR_UINT8);
}
void flgr1d_arith_complex_argument_fgUINT16(FLGR_Data1D *rdatdest, FLGR_Data1D *cdatsrc) {
  flgr_no_define_type_function(FLGR_UINT16);
}
void flgr1d_arith_complex_argument_fgUINT32(FLGR_Data1D *rdatdest, FLGR_Data1D *cdatsrc) {
  flgr_no_define_type_function(FLGR_UINT32);
}
void flgr1d_arith_complex_argument_fgINT8(FLGR_Data1D *rdatdest, FLGR_Data1D *cdatsrc) {
  flgr_no_define_type_function(FLGR_INT8);
}
void flgr1d_arith_complex_argument_fgINT16(FLGR_Data1D *rdatdest, FLGR_Data1D *cdatsrc) {
  flgr_no_define_type_function(FLGR_INT16);
}
void flgr1d_arith_complex_argument_fgINT32(FLGR_Data1D *rdatdest, FLGR_Data1D *cdatsrc) {
  flgr_no_define_type_function(FLGR_INT32);
}
void flgr1d_arith_complex_argument_fgFLOAT32(FLGR_Data1D *rdatdest, FLGR_Data1D *cdatsrc) {
  FLGR_MACRO_ARITH_COMPLEX_ARGUMENT_1D(fgFLOAT32,atan2f);
}
void flgr1d_arith_complex_argument_fgFLOAT64(FLGR_Data1D *rdatdest, FLGR_Data1D *cdatsrc) {
  FLGR_MACRO_ARITH_COMPLEX_ARGUMENT_1D(fgFLOAT64,atan2);
}
////////////////////////////////////////////////////////////////////////////
/*! Compute argument of a complex data
 *  @param rdatdest : pointer to FLGR_Data1D (real, spp=1)
 *  @param cdatsrc : pointer to FLGR_Data1D (complex, spp=2)
 *  @returns FLGR_RET_OK, ...
 */
//////////////////////////////////////////////////////////////////
FLGR_Ret flgr1d_arith_complex_argument(FLGR_Data1D *rdatdest, FLGR_Data1D *cdatsrc) {
  FLGR_Ret ret;

  FLGR_DECLARE_FUNCTION;
			
  if((rdatdest==NULL) || (cdatsrc==NULL)) {
    POST_ERROR("Null objects!\n");
    return FLGR_RET_NULL_OBJECT;
  }

  if(rdatdest->spp != 1) {
    POST_ERROR("destination must be scalar\n");
    return FLGR_RET_VECTOR_SIZE_ERROR;
  }

  if(cdatsrc->spp != 2) {
    POST_ERROR("source must be complex (spp=2)\n");
    return FLGR_RET_VECTOR_SIZE_ERROR;
  }

  if((ret = flgr1d_is_data_same_type(rdatdest,cdatsrc)) != FLGR_RET_OK) return ret;
  if((ret = flgr1d_is_data_same_length(rdatdest,cdatsrc)) != FLGR_RET_OK) return ret;

  FLGR_DISPATCH_PROCEDURE(rdatdest->type,flgr1d_arith_complex_argument,rdatdest,cdatsrc);

}




/////////////////////////////////////////////////////////////////////////
// macro for different type of flgr1d_arith_complex_module
/////////////////////////////////////////////////////////////////////////
#define FLGR_MACRO_ARITH_COMPLEX_BUILD_1D(dtype,opcos,opsin)		\
  dtype *parg = (dtype*) datarg->array;					\
  dtype *pmod = (dtype*) datmodule->array;				\
  dtype *idest = (dtype*) cdatdest->array;				\
  dtype val_arg,val_mod;						\
  int spp = cdatdest->spp;						\
  int length = cdatdest->length;					\
  int i,j;								\
									\
  FLGR_DECLARE_FUNCTION;						\
									\
  for(j=0,i=0 ; i<length ; j+=spp,i++) {				\
    val_arg = flgr_get_array_##dtype(parg,i);				\
    val_mod = flgr_get_array_##dtype(pmod,i);				\
    flgr_set_array_##dtype(idest,j,  val_mod * opcos(val_arg));		\
    flgr_set_array_##dtype(idest,j+1,  val_mod * opsin(val_arg));	\
  }									\
									\
  return

void flgr1d_arith_complex_build_fgBIT(FLGR_Data1D *cdatdest, FLGR_Data1D *datmodule, FLGR_Data1D *datarg) {
  flgr_no_define_type_function(FLGR_BIT);
}
void flgr1d_arith_complex_build_fgUINT8(FLGR_Data1D *cdatdest, FLGR_Data1D *datmodule, FLGR_Data1D *datarg) {
  flgr_no_define_type_function(FLGR_UINT8);
}
void flgr1d_arith_complex_build_fgUINT16(FLGR_Data1D *cdatdest, FLGR_Data1D *datmodule, FLGR_Data1D *datarg) {
  flgr_no_define_type_function(FLGR_UINT16);
}
void flgr1d_arith_complex_build_fgUINT32(FLGR_Data1D *cdatdest, FLGR_Data1D *datmodule, FLGR_Data1D *datarg) {
  flgr_no_define_type_function(FLGR_UINT32);
}
void flgr1d_arith_complex_build_fgINT8(FLGR_Data1D *cdatdest, FLGR_Data1D *datmodule, FLGR_Data1D *datarg) {
  flgr_no_define_type_function(FLGR_INT8);
}
void flgr1d_arith_complex_build_fgINT16(FLGR_Data1D *cdatdest, FLGR_Data1D *datmodule, FLGR_Data1D *datarg) {
  flgr_no_define_type_function(FLGR_INT16);
}
void flgr1d_arith_complex_build_fgINT32(FLGR_Data1D *cdatdest, FLGR_Data1D *datmodule, FLGR_Data1D *datarg) {
  flgr_no_define_type_function(FLGR_INT32);
}
void flgr1d_arith_complex_build_fgFLOAT32(FLGR_Data1D *cdatdest, FLGR_Data1D *datmodule, FLGR_Data1D *datarg) {
  FLGR_MACRO_ARITH_COMPLEX_BUILD_1D(fgFLOAT32,cosf,sinf);
}
void flgr1d_arith_complex_build_fgFLOAT64(FLGR_Data1D *cdatdest, FLGR_Data1D *datmodule, FLGR_Data1D *datarg) {
  FLGR_MACRO_ARITH_COMPLEX_BUILD_1D(fgFLOAT64,cos,sin);
}
////////////////////////////////////////////////////////////////////////////
/*! build of a complex data using module and argument
 *  @param cdatdest : pointer to FLGR_Data1D (complex, spp=2)
 *  @param datmodule : pointer to FLGR_Data1D (module real, spp=1)
 *  @param datarg : pointer to FLGR_Data1D (argument real, spp=1)
 *  @returns FLGR_RET_OK, ...
 */
//////////////////////////////////////////////////////////////////
FLGR_Ret flgr1d_arith_complex_build(FLGR_Data1D *cdatdest, FLGR_Data1D *datmodule, FLGR_Data1D *datarg) {
  FLGR_Ret ret;

  FLGR_DECLARE_FUNCTION;
			
  if((cdatdest==NULL) || (datmodule==NULL) || (datarg==NULL)) {
    POST_ERROR("Null objects!\n");
    return FLGR_RET_NULL_OBJECT;
  }

  if(cdatdest->spp != 2) {
    POST_ERROR("destination must be complex (spp=2)\n");
    return FLGR_RET_VECTOR_SIZE_ERROR;
  }

  if(datmodule->spp != 1) {
    POST_ERROR("module must be real (spp=1)\n");
    return FLGR_RET_VECTOR_SIZE_ERROR;
  }

  if(datarg->spp != 1) {
    POST_ERROR("argument must be real (spp=1)\n");
    return FLGR_RET_VECTOR_SIZE_ERROR;
  }

  if((ret = flgr1d_is_data_same_attributes(datmodule,datarg,__FUNCTION__)) != FLGR_RET_OK) return ret;

  if((ret = flgr1d_is_data_same_type(cdatdest,datmodule)) != FLGR_RET_OK) return ret;
  if((ret = flgr1d_is_data_same_length(cdatdest,datmodule)) != FLGR_RET_OK) return ret;

  FLGR_DISPATCH_PROCEDURE(cdatdest->type,flgr1d_arith_complex_build,cdatdest,datmodule,datarg);

}




/**********************************************************************************************/
/******************************************** 2D **********************************************/
/**********************************************************************************************/


#define FLGR_MACRO_ARITH_COMPLEX_MONOADIC(fct,dtype,dest,src)		\
  FLGR_Data1D **pdest = dest->row;					\
  FLGR_Data1D **p1 = src->row;						\
  int i;								\
									\
  FLGR_DECLARE_FUNCTION;						\
									\
  for(i=0 ; i<src->size_y ; i++,pdest++,p1++) {				\
    fct##_##dtype(*pdest,*p1);						\
  }									\
									\
  return

#define FLGR_MACRO_ARITH_COMPLEX_DIADIC(fct,dtype,dest,src1,src2)	\
  FLGR_Data1D **pdest = dest->row;					\
  FLGR_Data1D **p1 = src1->row;						\
  FLGR_Data1D **p2 = src2->row;						\
  int i;								\
									\
  FLGR_DECLARE_FUNCTION;						\
									\
  for(i=0 ; i<dest->size_y ; i++,pdest++,p1++,p2++) {			\
    fct##_##dtype(*pdest,*p1,*p2);					\
  }									\
									\
  return


void flgr2d_arith_complex_module_fgBIT(FLGR_Data2D *rdatdest, FLGR_Data2D *cdatsrc) {
  flgr_no_define_type_function(FLGR_BIT);
}
void flgr2d_arith_complex_module_fgUINT8(FLGR_Data2D *rdatdest, FLGR_Data2D *cdatsrc) {
  flgr_no_define_type_function(FLGR_UINT8);
}
void flgr2d_arith_complex_module_fgUINT16(FLGR_Data2D *rdatdest, FLGR_Data2D *cdatsrc) {
  flgr_no_define_type_function(FLGR_UINT16);
}
void flgr2d_arith_complex_module_fgUINT32(FLGR_Data2D *rdatdest, FLGR_Data2D *cdatsrc) {
  flgr_no_define_type_function(FLGR_UINT32);
}
void flgr2d_arith_complex_module_fgINT8(FLGR_Data2D *rdatdest, FLGR_Data2D *cdatsrc) {
  flgr_no_define_type_function(FLGR_INT8);
}
void flgr2d_arith_complex_module_fgINT16(FLGR_Data2D *rdatdest, FLGR_Data2D *cdatsrc) {
  flgr_no_define_type_function(FLGR_INT16);
}
void flgr2d_arith_complex_module_fgINT32(FLGR_Data2D *rdatdest, FLGR_Data2D *cdatsrc) {
  flgr_no_define_type_function(FLGR_INT32);
}
void flgr2d_arith_complex_module_fgFLOAT32(FLGR_Data2D *rdatdest, FLGR_Data2D *cdatsrc) {
  FLGR_MACRO_ARITH_COMPLEX_MONOADIC(flgr1d_arith_complex_module,fgFLOAT32,rdatdest,cdatsrc);
}
void flgr2d_arith_complex_module_fgFLOAT64(FLGR_Data2D *rdatdest, FLGR_Data2D *cdatsrc) {
  FLGR_MACRO_ARITH_COMPLEX_MONOADIC(flgr1d_arith_complex_module,fgFLOAT64,rdatdest,cdatsrc);
}
////////////////////////////////////////////////////////////////////////////
/*! Compute module of a complex data
 *  @param rdatdest : pointer to FLGR_Data2D (real, spp=1)
 *  @param cdatsrc : pointer to FLGR_Data2D (complex, spp=2)
 *  @returns FLGR_RET_OK, ...
 */
//////////////////////////////////////////////////////////////////
FLGR_Ret flgr2d_arith_complex_module(FLGR_Data2D *rdatdest, FLGR_Data2D *cdatsrc) {
  FLGR_Ret ret;

  FLGR_DECLARE_FUNCTION;
			
  if((rdatdest==NULL) || (cdatsrc==NULL)) {
    POST_ERROR("Null objects!\n");
    return FLGR_RET_NULL_OBJECT;
  }

  if(rdatdest->spp != 1) {
    POST_ERROR("destination must be scalar\n");
    return FLGR_RET_VECTOR_SIZE_ERROR;
  }

  if(cdatsrc->spp != 2) {
    POST_ERROR("source must be complex (spp=2)\n");
    return FLGR_RET_VECTOR_SIZE_ERROR;
  }

  if((ret = flgr2d_is_data_same_type(rdatdest,cdatsrc)) != FLGR_RET_OK) return ret;
  if((ret = flgr2d_is_data_same_size(rdatdest,cdatsrc)) != FLGR_RET_OK) return ret;

  FLGR_DISPATCH_PROCEDURE(rdatdest->type,flgr2d_arith_complex_module,rdatdest,cdatsrc);

}









void flgr2d_arith_complex_argument_fgBIT(FLGR_Data2D *rdatdest, FLGR_Data2D *cdatsrc) {
  flgr_no_define_type_function(FLGR_BIT);
}
void flgr2d_arith_complex_argument_fgUINT8(FLGR_Data2D *rdatdest, FLGR_Data2D *cdatsrc) {
  flgr_no_define_type_function(FLGR_UINT8);
}
void flgr2d_arith_complex_argument_fgUINT16(FLGR_Data2D *rdatdest, FLGR_Data2D *cdatsrc) {
  flgr_no_define_type_function(FLGR_UINT16);
}
void flgr2d_arith_complex_argument_fgUINT32(FLGR_Data2D *rdatdest, FLGR_Data2D *cdatsrc) {
  flgr_no_define_type_function(FLGR_UINT32);
}
void flgr2d_arith_complex_argument_fgINT8(FLGR_Data2D *rdatdest, FLGR_Data2D *cdatsrc) {
  flgr_no_define_type_function(FLGR_INT8);
}
void flgr2d_arith_complex_argument_fgINT16(FLGR_Data2D *rdatdest, FLGR_Data2D *cdatsrc) {
  flgr_no_define_type_function(FLGR_INT16);
}
void flgr2d_arith_complex_argument_fgINT32(FLGR_Data2D *rdatdest, FLGR_Data2D *cdatsrc) {
  flgr_no_define_type_function(FLGR_INT32);
}
void flgr2d_arith_complex_argument_fgFLOAT32(FLGR_Data2D *rdatdest, FLGR_Data2D *cdatsrc) {
  FLGR_MACRO_ARITH_COMPLEX_MONOADIC(flgr1d_arith_complex_argument,fgFLOAT32,rdatdest,cdatsrc);
}
void flgr2d_arith_complex_argument_fgFLOAT64(FLGR_Data2D *rdatdest, FLGR_Data2D *cdatsrc) {
  FLGR_MACRO_ARITH_COMPLEX_MONOADIC(flgr1d_arith_complex_argument,fgFLOAT64,rdatdest,cdatsrc);
}
////////////////////////////////////////////////////////////////////////////
/*! Compute module of a complex data
 *  @param rdatdest : pointer to FLGR_Data2D (real, spp=1)
 *  @param cdatsrc : pointer to FLGR_Data2D (complex, spp=2)
 *  @returns FLGR_RET_OK, ...
 */
//////////////////////////////////////////////////////////////////
FLGR_Ret flgr2d_arith_complex_argument(FLGR_Data2D *rdatdest, FLGR_Data2D *cdatsrc) {
  FLGR_Ret ret;

  FLGR_DECLARE_FUNCTION;
			
  if((rdatdest==NULL) || (cdatsrc==NULL)) {
    POST_ERROR("Null objects!\n");
    return FLGR_RET_NULL_OBJECT;
  }

  if(rdatdest->spp != 1) {
    POST_ERROR("destination must be scalar\n");
    return FLGR_RET_VECTOR_SIZE_ERROR;
  }

  if(cdatsrc->spp != 2) {
    POST_ERROR("source must be complex (spp=2)\n");
    return FLGR_RET_VECTOR_SIZE_ERROR;
  }

  if((ret = flgr2d_is_data_same_type(rdatdest,cdatsrc)) != FLGR_RET_OK) return ret;
  if((ret = flgr2d_is_data_same_size(rdatdest,cdatsrc)) != FLGR_RET_OK) return ret;

  FLGR_DISPATCH_PROCEDURE(rdatdest->type,flgr2d_arith_complex_argument,rdatdest,cdatsrc);

}






void flgr2d_arith_complex_build_fgBIT(FLGR_Data2D *cdatdest, FLGR_Data2D *datmodule, FLGR_Data2D *datarg) {
  flgr_no_define_type_function(FLGR_BIT);
}
void flgr2d_arith_complex_build_fgUINT8(FLGR_Data2D *cdatdest, FLGR_Data2D *datmodule, FLGR_Data2D *datarg) {
  flgr_no_define_type_function(FLGR_UINT8);
}
void flgr2d_arith_complex_build_fgUINT16(FLGR_Data2D *cdatdest, FLGR_Data2D *datmodule, FLGR_Data2D *datarg) {
  flgr_no_define_type_function(FLGR_UINT16);
}
void flgr2d_arith_complex_build_fgUINT32(FLGR_Data2D *cdatdest, FLGR_Data2D *datmodule, FLGR_Data2D *datarg) {
  flgr_no_define_type_function(FLGR_UINT32);
}
void flgr2d_arith_complex_build_fgINT8(FLGR_Data2D *cdatdest, FLGR_Data2D *datmodule, FLGR_Data2D *datarg) {
  flgr_no_define_type_function(FLGR_INT8);
}
void flgr2d_arith_complex_build_fgINT16(FLGR_Data2D *cdatdest, FLGR_Data2D *datmodule, FLGR_Data2D *datarg) {
  flgr_no_define_type_function(FLGR_INT16);
}
void flgr2d_arith_complex_build_fgINT32(FLGR_Data2D *cdatdest, FLGR_Data2D *datmodule, FLGR_Data2D *datarg) {
  flgr_no_define_type_function(FLGR_INT32);
}
void flgr2d_arith_complex_build_fgFLOAT32(FLGR_Data2D *cdatdest, FLGR_Data2D *datmodule, FLGR_Data2D *datarg) {
  FLGR_MACRO_ARITH_COMPLEX_DIADIC(flgr1d_arith_complex_build,fgFLOAT32,cdatdest,datmodule,datarg);
}
void flgr2d_arith_complex_build_fgFLOAT64(FLGR_Data2D *cdatdest, FLGR_Data2D *datmodule, FLGR_Data2D *datarg) {
  FLGR_MACRO_ARITH_COMPLEX_DIADIC(flgr1d_arith_complex_build,fgFLOAT64,cdatdest,datmodule,datarg);
}
////////////////////////////////////////////////////////////////////////////
/*! build of a complex data using module and argument
 *  @param cdatdest : pointer to FLGR_Data2D (complex, spp=2)
 *  @param datmodule : pointer to FLGR_Data2D (module real, spp=1)
 *  @param datarg : pointer to FLGR_Data2D (argument real, spp=1)
 *  @returns FLGR_RET_OK, ...
 */
//////////////////////////////////////////////////////////////////
FLGR_Ret flgr2d_arith_complex_build(FLGR_Data2D *cdatdest, FLGR_Data2D *datmodule, FLGR_Data2D *datarg) {
  FLGR_Ret ret;

  FLGR_DECLARE_FUNCTION;
			
  if((cdatdest==NULL) || (datmodule==NULL) || (datarg==NULL)) {
    POST_ERROR("Null objects!\n");
    return FLGR_RET_NULL_OBJECT;
  }

  if(cdatdest->spp != 2) {
    POST_ERROR("destination must be complex (spp=2)\n");
    return FLGR_RET_VECTOR_SIZE_ERROR;
  }

  if(datmodule->spp != 1) {
    POST_ERROR("module must be real (spp=1)\n");
    return FLGR_RET_VECTOR_SIZE_ERROR;
  }

  if(datarg->spp != 1) {
    POST_ERROR("argument must be real (spp=1)\n");
    return FLGR_RET_VECTOR_SIZE_ERROR;
  }

  if((ret = flgr2d_is_data_same_attributes(datmodule,datarg,__FUNCTION__)) != FLGR_RET_OK) return ret;

  if((ret = flgr2d_is_data_same_type(cdatdest,datmodule)) != FLGR_RET_OK) return ret;
  if((ret = flgr2d_is_data_same_size(cdatdest,datmodule)) != FLGR_RET_OK) return ret;

  FLGR_DISPATCH_PROCEDURE(cdatdest->type,flgr2d_arith_complex_build,cdatdest,datmodule,datarg);

}





//! @}

